function [mydemo, cleanup] = demo_rbf_rr_2
%
% Demo of ridge regression with RBFs.
%

% Initialise number of chunks in mydemo.
n = 0;

n = n + 1;
mydemo(n) = struct( ...
  'comments', {{
              'This is the demo for the rbf_rr_2 method.', ...
              '-----------------------------------------', ...
              '', ...
              'rbf_rr_2 is an algorithm for regression and classification', ...
              'which uses radial basis functions and weight decay (ridge', ...
              'regression) to generate the data model. It can automatically', ...
              'estimate the optimal regularisation parameter.'}}, ...
  'commands', '%clear conf', ...
  'question', '', ...
  'optional', '');

n = n + 1;
mydemo(n) = struct( ...
  'comments', {{ ...
              'First, let''s try the method on a relatively easy 2D problem,', ...
              'the ''sine2'' data set. We''ll first get training and test', ...
              'sets for the problem.'}}, ...
  'commands', {{ ...
              '[X, y, train] = get_data(''sine2'');', ...
              'test = train;', ...
              'test.std = 0;', ...
              'test.ord = 1;', ...
              'test.p = 1600;', ...
              '[Xt, yt, test] = get_data(test);'}}, ...
  'question', '', ...
  'optional', '');

n = n + 1;
mydemo(n) = struct( ...
  'comments', 'Next, plot the data.', ...
  'commands', {{ ...
              'fig = get_fig(''rbf_rr_2 demo'');', ...
              'hold off', ...
              'p = test.p;', ...
              'q = sqrt(p);', ...
              'Yt = zeros(q, q);', ...
              'Yt(:) = yt;', ...
              'v1 = linspace(test.x1(1), test.x2(1), q);', ...
              'v2 = linspace(test.x1(2), test.x2(2), q);', ...
              'surfl(v1, v2, Yt)', ...
              '%light(''Position'', [0 0 1], ''Style'', ''infinite'');', ...
              '%colormap(gray)', ...
              '%shading interp', ...
              'hold on', ...
              'plot3(X(1,:), X(2,:), y, ''ko'')', ...
              '%xlabel(''x1'', ''FontSize'', 16)', ...
              '%ylabel(''x2'', ''FontSize'', 16)', ...
              '%zlabel(''y'', ''FontSize'', 16, ''Rotation'', 0)'}}, ...
  'question', '', ...
  'optional', '');

n = n + 1;
mydemo(n) = struct( ...
  'comments', {{ ...
              'Now let''s estimate a model and use it to predict the test set.', ...
              'We''ll try putting our trust rbf_rr_2''s default configuration.', ...
              '', ...
              'This may take a few seconds.'}}, ...
  'commands', {{ ...
              '[C, R, w] = rbf_rr_2(X, y);', ...
              'Ht = rbf_dm(Xt, C, R);', ...
              'ft = Ht * w;'}}, ...
  'question', '', ...
  'optional', '');

n = n + 1;
mydemo(n) = struct( ...
  'comments', {{ ...
              'We can evaluate the accuracy of the result in two ways.', ...
              'First, we can plot the test set predictions and the actual', ...
              'test set outputs together. The two surfaces should be', ...
              'pretty close.'}}', ...
  'commands', {{ ...
              'Ft = zeros(q, q);', ...
              'Ft(:) = ft;', ...
              'hold off', ...
              'surfl(v1, v2, Ft)', ...
              'hold on', ...
              'surfl(v1, v2, Yt)', ...
              '%light(''Position'', [0 0 1], ''Style'', ''infinite'');', ...
              '%colormap(gray)', ...
              '%shading interp', ...
              '%xlabel(''x1'', ''FontSize'', 16)', ...
              '%ylabel(''x2'', ''FontSize'', 16)', ...
              '%zlabel(''y'', ''FontSize'', 16, ''Rotation'', 0)'}}, ...
  'question', '', ...
  'optional', '');

n = n + 1;
mydemo(n) = struct( ...
  'comments', {{ ...
              'Secondly, we can evaluate the root mean square error.', ...
              'We''ll remember this figure (rmse1) for later comparison.'}}, ...
  'commands', {{ ...
              'rmse1 = sqrt(sum((yt - ft).^2) / test.p);', ...
              'disp(rmse1)'}}, ...
  'question', '', ...
  'optional', '');

n = n + 1;
mydemo(n) = struct( ...
  'comments', {{ ...
              'We might be able to do better than this by changing, for example,', ...
              'the default RBF size. However, it''s not clear whether we should', ...
              'increase or decrease it. We can test the effect of inflating or', ...
              'deflating all RBFs together by setting the configuration field', ...
              '''scales''. The algorithm will choose the best scaling factor', ...
              'and report it''s choice in info.scale.', ...
              '', ...
              'Another improvement is to give the alorithm a few different guesses', ...
              'for the initial value of the regularisation parameter (the default', ...
              'is a single guess of 1).', ...
              '', ...
              'This will take a bit longer than the previous call.'}}, ...
  'commands', {{ ...
              'conf.scales = [0.75 1.00 1.25];', ...
              'conf.lambdas = [1e-6 1e-3 1];', ...
              '[C, R, w, info] = rbf_rr_2(X, y, conf);', ...
              'disp(info.scale)'}}, ...
  'question', '', ...
  'optional', '');

n = n + 1;
mydemo(n) = struct( ...
  'comments', {{ ...
              'Allowing the algorithm some flexibility over the RBF size and the', ...
              'initial guess lambda, gives it a chance to find a more accurate', ...
              'model by finding the combination which leads to the lowest value', ...
              'for the model selection criterion (and hopefully therefore, but not', ...
              'necessarily, a lower test set error). If this has worked then rmse2', ...
              'should be less than rmse1'}}, ...
  'commands', {{ ...
              'Ht = rbf_dm(Xt, C, R);', ...
              'ft = Ht * w;', ...
              'rmse2 = sqrt(sum((yt - ft).^2) / test.p);', ...
              'disp(rmse1)', ...
              'disp(rmse2)'}}, ...
  'question', '', ...
  'optional', '');

n = n + 1;
mydemo(n) = struct( ...
  'comments', 'What about the two surfaces? Do they look any closer now?', ...
  'commands', {{ ...
              'Ft(:) = ft;', ...
              'hold off', ...
              'surfl(v1, v2, Ft)', ...
              'hold on', ...
              'surfl(v1, v2, Yt)', ...
              '%light(''Position'', [0 0 1], ''Style'', ''infinite'');', ...
              '%colormap(gray)', ...
              '%shading interp', ...
              '%xlabel(''x1'', ''FontSize'', 16)', ...
              '%ylabel(''x2'', ''FontSize'', 16)', ...
              '%zlabel(''y'', ''FontSize'', 16, ''Rotation'', 0)'}}, ...
  'question', '', ...
  'optional', '');

n = n + 1;
mydemo(n) = struct( ...
  'comments', 'End of rbf_rr_2 demo.', ...
  'commands', '', ...
  'question', '', ...
  'optional', '');

% Define the command(s) necessary to cleanup after the demo (e.g. close figures).
cleanup = 'if exist(''fig'', ''var'') if ~isempty(find(findobj(''type'',''figure'') == fig)) close(fig); end; end';
